﻿using System;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace Trentacular.SharePoint.Features.Web.UI.WebParts
{
    public class BaseSPWebPart : WebEditableWebPart
    {
        private SPContext _spContext;
        protected SPContext SPContext
        {
            get
            {
                if (_spContext == null)
                    _spContext = SPContext.Current;
                return _spContext;
            }
        }

        protected SPWeb Web { get { return SPContext.Web; } }
        protected SPUser CurrentUser { get { return Web.CurrentUser; } }

        private bool _error = false;

        protected sealed override void OnInit(EventArgs e)
        {
            SafeHandleEvent(delegate()
            {
                OnInitHandler(e);
            });
        }

        protected sealed override void CreateChildControls()
        {
            SafeHandleEvent(delegate()
            {
                CreateChildControlsHandler();
            });
        }

        /// <summary>
        /// Ensures that the CreateChildControls() is called before events.
        /// Use CreateControls() to create your controls.
        /// </summary>
        protected sealed override void OnLoad(EventArgs e)
        {
            SafeHandleEvent(delegate()
            {
                EnsureChildControls();
                OnLoadHandler(e);
            });
        }

        protected sealed override void OnPreRender(EventArgs e)
        {
            SafeHandleEvent(delegate()
            {
                OnPreRenderHandler(e);
            });
        }

        protected sealed override void RenderContents(HtmlTextWriter writer)
        {
            SafeHandleEvent(writer, delegate()
            {
                RenderContentsHandler(writer);
            });
        }

        protected virtual void OnInitHandler(EventArgs e) { base.OnInit(e); }
        protected virtual void CreateChildControlsHandler() { base.CreateChildControls(); }
        protected virtual void OnLoadHandler(EventArgs e) { base.OnLoad(e); }
        protected virtual void OnPreRenderHandler(EventArgs e) { base.OnPreRender(e); }
        protected virtual void RenderContentsHandler(HtmlTextWriter writer) { base.RenderContents(writer); }

        protected virtual void SmartRedirect(string defaultUrl)
        {
            SPUtility.Redirect(defaultUrl, SPRedirectFlags.UseSource, Context);
        }

        private void SafeHandleEvent(Action action)
        {
            SafeHandleEvent(null, action);
        }

        private void SafeHandleEvent(HtmlTextWriter writer, Action action)
        {
            if (!_error)
            {
                try
                {
                    action();
                }
                catch (Exception ex)
                {
                    // Clear all child controls and add an error message for display
                    this._error = true;
                    this.Controls.Clear();

                    var errorMessage = new HtmlGenericControl("p") { InnerText = Context.Server.HtmlEncode(ex.Message) };
                    errorMessage.Attributes["class"] = "error";
                    this.Controls.Add(errorMessage);

                    if (writer != null)
                        errorMessage.RenderControl(writer);
                }
            }
        }

        protected string GetToolPaneLink(string msg)
        {
            return string.Format("<a href=\"javascript:MSOTlPn_ShowToolPane2('Edit','{0}');\">{1}</a>", this.ID, msg);
        }
    }
}
